﻿namespace CloudNinja.Metering.Providers.Configuration.BlobBandwidth
{
    using System.Configuration;
    using System.Linq;

    using CloudNinja.Metering.Common;
    using CloudNinja.Metering.Common.Configuration;
    using CloudNinja.Metering.Common.Logging;
    using CloudNinja.Metering.Data;
    using CloudNinja.Metering.Providers;
    using CloudNinja.Metering.Providers.AzureBlob;
    using CloudNinja.Metering.Providers.WebRole;

    using Microsoft.Practices.Unity;

    public class BlobBandwidthProviderElement : ProviderElement
    {
        [ConfigurationProperty("BlobBandwidthMeteringProviderSettings")]
        public BlobBandwidthMeteringProviderSettings BlobBandwidthMeteringProviderSettings
        {
            get
            {
                return this["BlobBandwidthMeteringProviderSettings"] as BlobBandwidthMeteringProviderSettings;
            }

            set
            {
                this["BlobBandwidthMeteringProviderSettings"] = value;
            }
        }

        public override void RegisterType(IUnityContainer container, MeteringSection meteringConfiguration)
        {
            var storageAccounts = from object blobSizeMeteringProviderSetting in
                                      this.BlobBandwidthMeteringProviderSettings.StorageAccounts
                                  select blobSizeMeteringProviderSetting as BlobBandwidthCollectionElement;
            var storageAccountsDict = storageAccounts.ToDictionary(
                setting => setting.Name,
                setting =>
                new TenantsStorageAccount
                    {
                        ConnectionString = setting.ConnectionString,
                        TenantIdPattern =
                            setting.TenantIdPattern.Equals(string.Empty)
                                ? this.BlobBandwidthMeteringProviderSettings.DefaultTenantIdPattern
                                : setting.TenantIdPattern
                    });

            if (!container.IsRegistered(typeof(IParserBookmarkRepository)))
            {
                var azureStorageLogParsingStateRepositoryCtor =
                    new InjectionConstructor(
                        this.BlobBandwidthMeteringProviderSettings.BlobBandwidthLogsParserBookmarkRepository, container.Resolve<ILogger>());
                container.RegisterType<IParserBookmarkRepository, AzureStorageParserBookmarkRepository>(
                    new ContainerControlledLifetimeManager(), azureStorageLogParsingStateRepositoryCtor);
            }

            var storageSizeInjectionConstructor = new InjectionConstructor(
                this.CollectInterval,
                storageAccountsDict,
                container.Resolve<ILogger>(),
                container.Resolve<IParserBookmarkRepository>(),
                container.Resolve<IMeteringRepository>(),
                container.Resolve<IMeteringContext>());

            container.RegisterType<IMeteringProvider, BlobBandwidthProvider>(
                typeof(BlobBandwidthProvider).ToString(),
                new ContainerControlledLifetimeManager(),
                storageSizeInjectionConstructor);
        }

        protected override object OnRequiredPropertyNotFound(string name)
        {
            // HACK: Do not really understand why it comes here with these properties, which is clearly defined above.
            return name.Equals("BlobBandwidthMeteringProviderSettings") ? null : base.OnRequiredPropertyNotFound(name);
        }
    }
}
